var hx = require("hbuilderx");
const fs = require('fs');
const path = require('path');
const babel = require('@babel/core');

// 插件配置
let isEnabled = true;
let currentPlatform = null;
let statusBarItem = null;

// 平台映射表
const platformMap = {
	'app': 'APP',
	'h5': 'WEB',
	'mp-alipay': 'MP-ALIPAY',
	'mp-baidu': 'MP-BAIDU',
	'mp-jd': 'MP-JD',
	'mp-kuaishou': 'MP-KUAISHOU',
	'mp-lark': 'MP-LARK',
	'mp-qq': 'MP-QQ',
	'mp-toutiao': 'MP-TOUTIAO',
	'mp-weixin': 'MP-WEIXIN',
	'mp-360': 'MP-360',
	'mp-xhs': 'MP-XHS',
	'quickapp-webview': 'QUICKAPP-WEBVIEW',
	'quickapp-webview-union': 'QUICKAPP-WEBVIEW-UNION',
	'quickapp-webview-huawei': 'QUICKAPP-WEBVIEW-HUAWEI',
};

// 该方法将在插件激活的时候调用
function activate(context) {
	// 创建状态栏项
	createStatusBarItem();

	// 注册命令：启用/禁用平台转换
	let toggleCommand = hx.commands.registerCommand('platformTransformer.toggle', async () => {
		// 显示确认对话框让用户选择是启用还是禁用
		const buttons = ['启用', '禁用'];
		const result = await hx.window.showInformationMessage(
			`请选择是否启用平台转换功能？当前状态：${isEnabled ? '已启用' : '已禁用'}`,
			{
				modal: true
			},
			...buttons
		);

		if (result === '启用') {
			isEnabled = true;
			hx.window.showInformationMessage('平台转换器已启用');
		} else if (result === '禁用') {
			isEnabled = false;
			hx.window.showInformationMessage('平台转换器已禁用');
		}

		// 更新状态栏
		updateStatusBarItem();
	});

	// 注册编译器钩子
	const compilerHook = hx.App.registerCompilerHook('uni-app', {
		onBeforeCompile: function(param, callback) {
			// 编译前的处理，从编译参数中获取平台信息
			try {
				// 从编译参数中获取平台信息
				const uniPlatform = param.platform || '';

				// 根据平台映射表获取对应的平台标识
				if (platformMap[uniPlatform]) {
					currentPlatform = platformMap[uniPlatform];
					console.log(`[Platform Transformer] 当前编译平台: ${uniPlatform} => ${currentPlatform}`);

					// 更新状态栏
					updateStatusBarItem();

					// 显示通知
					hx.window.showInformationMessage(`正在为 ${getPlatformDisplayName(uniPlatform)} 平台编译，转换器${isEnabled ? '已启用' : '已禁用'}`);
				} else {
					// 默认使用WEB平台
					currentPlatform = 'WEB';
					console.log(`[Platform Transformer] 未识别的平台: ${uniPlatform}，使用默认平台: WEB`);

					// 更新状态栏
					updateStatusBarItem();
				}
			} catch (error) {
				console.error('[Platform Transformer] 获取平台信息失败:', error);
				currentPlatform = 'WEB'; // 默认使用WEB平台

				// 更新状态栏
				updateStatusBarItem();
			}

			callback(null);
		},
		onAfterCompile: function(param, callback) {
			// 编译后的处理
			if (!isEnabled || !currentPlatform) {
				callback(null);
				return;
			}

			try {
				// 获取编译后的文件列表
				const files = param.fileList || [];
				const processedFiles = [];

				// 处理每个文件
				for (const file of files) {
					// 只处理js、ts、vue、nvue文件
					if (!/\.(js|ts|vue|nvue)$/.test(file.path)) {
						continue;
					}

					// 读取文件内容
					const content = fs.readFileSync(file.path, 'utf-8');

					// 创建babel插件
					const babelPlugin = createBabelPlugin(currentPlatform);

					// 处理文件内容
					const processedContent = processFile(file.path, content, babelPlugin);

					// 如果处理成功，写回文件
					if (processedContent) {
						fs.writeFileSync(file.path, processedContent, 'utf-8');
						processedFiles.push(path.basename(file.path));
					}
				}

				if (processedFiles.length > 0) {
					hx.window.showInformationMessage(`已完成平台转换(${getPlatformDisplayName(param.platform)})，处理了${processedFiles.length}个文件`);
				}

				callback(null);
			} catch (error) {
				console.error('[Platform Transformer] 平台转换器错误:', error);
				callback(error);
			}
		}
	});

	// 订阅销毁钩子，插件禁用的时候，自动注销命令和钩子
	context.subscriptions.push(toggleCommand, compilerHook, statusBarItem);
}

// 创建状态栏项
function createStatusBarItem() {
	statusBarItem = hx.window.createStatusBarItem();
	statusBarItem.text = "平台转换";
	statusBarItem.tooltip = "点击切换平台转换器状态";
	statusBarItem.command = "platformTransformer.toggle";
	updateStatusBarItem();
	statusBarItem.show();
}

// 更新状态栏项
function updateStatusBarItem() {
	if (!statusBarItem) return;

	const platformText = currentPlatform ? `(${currentPlatform})` : '';
	statusBarItem.text = `平台转换${platformText}: ${isEnabled ? '已启用' : '已禁用'}`;
	statusBarItem.tooltip = `点击切换平台转换器状态\n当前平台: ${currentPlatform || '未知'}\n状态: ${isEnabled ? '已启用' : '已禁用'}`;
}

// 获取平台显示名称
function getPlatformDisplayName(platform) {
	const displayNames = {
		'app': 'App',
		'h5': 'H5/Web',
		'mp-alipay': '支付宝小程序',
		'mp-baidu': '百度小程序',
		'mp-jd': '京东小程序',
		'mp-kuaishou': '快手小程序',
		'mp-lark': '飞书小程序',
		'mp-qq': 'QQ小程序',
		'mp-toutiao': '抖音小程序',
		'mp-weixin': '微信小程序',
		'mp-360': '360小程序',
		'mp-xhs': '小红书小程序',
		'quickapp-webview': '快应用',
		'quickapp-webview-union': '快应用联盟',
		'quickapp-webview-huawei': '快应用华为',
	};

	return displayNames[platform] || platform || '未知平台';
}

// 创建babel插件
function createBabelPlugin(platform) {
	// 检查平台是否是小程序
	const isMp = platform ? platform === 'MP' : platform.startsWith('MP_');

	// 返回一个Babel插件配置
	return function() {
		return {
			visitor: {
				// 查找并处理exe()调用，这样能捕获整个链式调用
				CallExpression(path) {
					// 检查是否是exe()调用
					if (
						path.node.callee.type === 'MemberExpression' &&
						path.node.callee.property.type === 'Identifier' &&
						path.node.callee.property.name === 'exe'
					) {
						// 找到链式调用的起点（PlatformChain.with）
						let chainStart = null;
						let currentNode = path.node.callee.object;
						const platformCallbacks = new Map();
						let defaultCallback = null;

						// 获取exe调用的参数，用于传递给选中的回调函数
						const exeArguments = path.node.arguments || [];

						// 回溯查找链式调用的起点和所有平台方法
						while (currentNode && currentNode.type === 'CallExpression') {
							if (
								currentNode.callee.type === 'MemberExpression' &&
								currentNode.callee.property.type === 'Identifier'
							) {
								const methodName = currentNode.callee.property.name;

								// 检查是否找到了链式调用的起点（with方法）
								if (
									methodName === 'with' &&
									currentNode.callee.object.type === 'Identifier' &&
									currentNode.callee.object.name === 'PlatformChain'
								) {
									chainStart = currentNode;
									if (currentNode.arguments && currentNode.arguments.length > 0) {
										defaultCallback = currentNode.arguments[0];
									}
									break;
								}

								// 收集平台方法
								const platformMethodMap = {
									'app': 'APP',
									'appPlus': 'APP-PLUS',
									'appNvue': 'APP-NVUE',
									'web': 'WEB',
									'mpWeixin': 'MP-WEIXIN',
									'mpAlipay': 'MP-ALIPAY',
									'mpBaidu': 'MP-BAIDU',
									'mpToutiao': 'MP-TOUTIAO',
									'mpLark': 'MP-LARK',
									'mpQq': 'MP-QQ',
									'mpKuaishou': 'MP-KUAISHOU',
									'mpJd': 'MP-JD',
									'mp360': 'MP-360',
									'mpHarmony': 'MP-HARMONY',
									'mpXhs': 'MP-XHS',
									'mp': 'MP',
									'quickappWebview': 'QUICKAPP-WEBVIEW',
									'quickappWebviewUnion': 'QUICKAPP-WEBVIEW-UNION',
									'quickappWebviewHuawei': 'QUICKAPP-WEBVIEW-HUAWEI',
								};

								if (Object.keys(platformMethodMap).includes(methodName)) {
									if (currentNode.arguments && currentNode.arguments.length > 0) {
										const platformKey = platformMethodMap[methodName];
										platformCallbacks.set(platformKey, currentNode.arguments[0]);
									}
								} else if (methodName === 'case' && currentNode.arguments && currentNode.arguments.length > 1) {
									// 支持case方法，第一个参数是平台数组，第二个参数是回调函数
									if (currentNode.arguments[0].type === 'ArrayExpression' && currentNode.arguments[0].elements) {
										const platforms = currentNode.arguments[0].elements
											.filter((element) => element.type === 'StringLiteral')
											.map((element) => element.value);

										const callback = currentNode.arguments[1];
										platforms.forEach((platform) => {
											if (Object.keys(platformMethodMap).includes(platform)) {
												const platformKey = platformMethodMap[platform];
												platformCallbacks.set(platformKey, callback);
											}
										});
									}
								}
							}

							// 继续向上查找链式调用
							if (currentNode.callee && currentNode.callee.object) {
								currentNode = currentNode.callee.object;
							} else {
								break;
							}
						}

						// 如果找到了链式调用的起点
						if (chainStart) {
							// 确定哪个回调应该被保留
							let resultCallback = null;

							// 优先检查当前平台
							if (platformCallbacks.has(platform)) {
								resultCallback = platformCallbacks.get(platform);
							}
							// 检查通用小程序
							else if (isMp && platformCallbacks.has('MP')) {
								resultCallback = platformCallbacks.get('MP');
							}
							// 使用默认回调
							else if (defaultCallback) {
								resultCallback = defaultCallback;
							}

							// 如果找到了匹配的回调，替换整个PlatformChain调用
							if (resultCallback) {
								// 创建一个函数调用，将exe()的参数传递给选中的回调函数
								const replacement = babel.types.callExpression(resultCallback, exeArguments);
								path.replaceWith(replacement);
							}
						}
					}
				}
			}
		};
	};
}

// 处理单个文件
function processFile(filePath, content, babelPlugin) {
	// 处理JavaScript和TypeScript文件
	if (/\.(js|ts)$/.test(filePath)) {
		// 使用babel转换代码
		const result = babel.transform(content, {
			filename: filePath,
			plugins: [babelPlugin]
		});

		return result ? result.code || null : null;
	}

	// 处理Vue、Nvue文件
	if (/\.(vue|nvue)$/.test(filePath)) {
		// 提取<script>标签内容
		const scriptInfo = extractScriptContent(content);

		if (scriptInfo) {
			const {scriptContent, startIdx, endIdx} = scriptInfo;

			// 使用babel转换脚本内容
			const result = babel.transform(scriptContent, {
				filename: filePath + '.js', // 添加.js后缀以支持语法
				plugins: [babelPlugin]
			});

			if (result && result.code) {
				// 替换原始脚本内容
				const scriptTagStart = content.substring(startIdx, startIdx + content.substring(startIdx).indexOf('>') + 1);
				return content.substring(0, startIdx) +
					scriptTagStart +
					result.code +
					'</script>' +
					content.substring(endIdx);
			}
		}
	}

	return null;
}

// 提取Vue/Nvue文件中的脚本内容
function extractScriptContent(code) {
	// 匹配<script>标签内容，包括带有lang="ts"等属性的情况
	const scriptMatch = code.match(/<script(\s+[^>]*)?>([\s\S]*?)<\/script>/i);

	if (scriptMatch) {
		const fullMatch = scriptMatch[0];
		const scriptContent = scriptMatch[2];
		const startIdx = code.indexOf(fullMatch);
		const endIdx = startIdx + fullMatch.length;

		return {
			scriptContent,
			startIdx,
			endIdx
		};
	}

	return null;
}

//该方法将在插件禁用的时候调用（目前是在插件卸载的时候触发）
function deactivate() {
	// 清理资源
	if (statusBarItem) {
		statusBarItem.dispose();
		statusBarItem = null;
	}
}

module.exports = {
	activate,
	deactivate
}
